package com.ibm.cloud.banking.config;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * replace desc in here
 *
 * @author HanDong
 * @date 2020/6/10
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {

  @Value("${info.app.title}")
  private String appTitle;

  @Value("${info.app.description}")
  private String appDescription;

  @Value("${info.app.version}")
  private String appVersion;

  @Value("${info.app.contract.name}")
  private String appContractName;

  @Value("${info.app.contract.url}")
  private String appContractUrl;

  @Value("${info.app.contract.email}")
  private String appContractEmail;

  @Value("${swagger.host}")
  private String swaggerHost;

  @Bean
  public Docket customDocket() {


    return new Docket(DocumentationType.OAS_30)
        .host("").apiInfo(
            new ApiInfo(
                appTitle,
                appDescription,
                appVersion,
                null,
                new Contact(appContractName, appContractUrl, appContractEmail),
                null,
                null,
                Collections.EMPTY_LIST))
        .select()
        //.paths(PathSelectors.any())
        .build();
  }



  @Bean
  public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
    return new BeanPostProcessor() {

      @Override
      public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
          customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
        }
        return bean;
      }

      private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
//        List<T> copy = mappings.stream()
//                .filter(mapping -> mapping.getPatternParser() == null)
//                .collect(Collectors.toList());
//        mappings.clear();
//        mappings.addAll(copy);
      }

      @SuppressWarnings("unchecked")
      private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
        try {
          Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
          field.setAccessible(true);
          return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
        } catch (IllegalArgumentException | IllegalAccessException e) {
          throw new IllegalStateException(e);
        }
      }
    };
  }

}
